package com.hqyj.freemovie.front.interview;

/*
 * 三个线程
 *
 * 一个生产者线程：妈妈做馒头的线程。
 * 两个消费者线程：两个儿子不停的吃馒头的线程。
 *
 * 临界资源是锅。
 * */

import java.util.Random;
import java.util.Stack;

class Pot {
    public static final int MAX_NUM = 100; //妈妈一共做100个馒头结束了。
    public static final int POT_LEN = 10; //表示这个锅临界资源最多只能蒸10个馒头
    public Stack<Integer> stack = new Stack<Integer>(); //锅临界资源

    public static int iCounter = 0;

    public int bigSonNumber = 0; //统计大林吃了多个馒头。
    public int smallSonNumber = 0; //统计小林吃了多少各馒头。

    //往锅里添加馒头。
    public void makeCake() {
        Pot.iCounter++;
        stack.push(Pot.iCounter);
        System.out.println("妈妈做完了第:" + Pot.iCounter + "个馒头....");

    }

    //从锅里取馒头吃
    public void eatCake() {
        int temp = stack.pop();
        String name = Thread.currentThread().getName();
        if ("大林".equals(name)) {
            bigSonNumber++;
        } else {
            smallSonNumber++;
        }
        System.out.println(name + "吃掉第" + temp + "个馒头....");

    }

}

//生产者的线程类

class Producer implements Runnable {

    private Pot pot;

    public Producer(Pot pot) {
        this.pot = pot;
    }

    @Override
    public void run() {
        try {
            while (true) {
                //妈妈不停的做馒头。。。
                synchronized (pot) {
                    //判断馒头是否做完了。退出线程
                    if (Pot.iCounter >= 100) {
                        System.out.println("100个馒头做完了，明年接着做馒头....");
                        //唤醒儿子吃馒头。
                        pot.notifyAll();
                        break;
                    }

                    //判断这个锅是不是满了。如果满了。怎么办。
                    if (pot.stack.size() == Pot.POT_LEN) {
                        //说明锅里的馒头已经装满了.
                        pot.notifyAll(); //唤醒儿子线程过来吃馒头。
                        pot.wait();
                    } else {
                        pot.makeCake();
                        try {
                            Thread.sleep(20);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

class Consumer implements Runnable {
    private Pot pot;

    public Consumer(Pot pot) {
        this.pot = pot;
    }

    @Override
    public void run() {
        try {
            while (true) {
                synchronized (pot) {
                    //儿子不停的吃馒头..
                    if (Pot.iCounter >= 100 && pot.stack.empty()) {
                        System.out.println("100个馒头全部吃完了,明年继续吃馒头....");
                        break;
                    }
                    //判断锅现在是不是空的。
                    if (pot.stack.isEmpty()) {
                        //说明锅是空的。
                        pot.notifyAll(); //唤醒妈妈过来做馒头。
                        pot.wait();
                    } else {
                        pot.eatCake();

                        if (Pot.iCounter >= 100 && pot.stack.empty()) {
                            System.out.println("100个馒头全部吃完了,明年继续吃馒头....");
                            pot.notifyAll(); //唤醒妈妈过来做馒头。
                            break;
                        }

                        try {
                            //int randomTimer = Math.abs(new Random(50).nextInt());
                            pot.notifyAll(); //唤醒妈妈过来做馒头。
                            pot.wait();

                            Thread.sleep(5);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

public class ProducerAndConsumerDemo {

    public static void main(String[] args) {

        Pot pot = new Pot();
        Producer mother = new Producer(pot);
        Consumer consumer = new Consumer(pot);

        //生成三个线程
        Thread motherThead = new Thread(mother);
        Thread bigSonThread = new Thread(consumer, "大林");
        Thread smallSonThread = new Thread(consumer, "小林");

        motherThead.start();
        bigSonThread.start();
        smallSonThread.start();

        try {
            motherThead.join();
            bigSonThread.join();
            smallSonThread.join();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        System.out.println("大林吃了：" + pot.bigSonNumber + "个馒头！");
        System.out.println("小林吃了：" + pot.smallSonNumber + "个馒头！");
    }
}
